package pl.edu.pk.mech.kkbus.service;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.apache.commons.codec.digest.DigestUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pl.edu.pk.mech.kkbus.component.ExternalEmailSender;
import pl.edu.pk.mech.kkbus.component.MyEntityManagerFactory;
import pl.edu.pk.mech.kkbus.entities.Award;
import pl.edu.pk.mech.kkbus.entities.User;
import pl.edu.pk.mech.kkbus.entities.Exchange;

@Service
public class ExchangeService {
 
    @Autowired
    ExternalEmailSender emailSender;
    
    @Autowired
    UserService userService;
    
    @Autowired
    AwardService awardService;
    
    EntityManagerFactory emf = MyEntityManagerFactory.get();
    
    public boolean createExchange(pl.edu.pk.mech.kkbus.dto.Exchange data) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            
            EntityTransaction txn = em.getTransaction();
            txn.begin();
            
            try {
                Award award = em.find(Award.class, new Long(data.getAwardId()));
                User user = em.find(User.class, new Long(data.getUserId()));

                // Weryfikacja
                if (award == null) return false;
                if (user == null) return false;
                if (award.getQuantity() == 0) return false;
                if (user.getPoints() < award.getPoints()) return false;

                award.setQuantity(award.getQuantity() - 1);
                user.setPoints(user.getPoints() - award.getPoints());

                String hash = DigestUtils.md5Hex(String.valueOf(new Date()) + "pHe1Ux7kJA");
                Exchange exchange = new Exchange(hash, data.getUserId(), data.getAwardId());
                em.persist(exchange);

                String message = "Zamówiłeś: "+ award.getName() +" Twój kod weryfikujący: " + exchange.getHash();
                emailSender.send(user.getEmail(), "KKBus - Nagroda", message);
            
                // Zapis do DataStore
                txn.commit();
            } catch(Exception e) {
                e.printStackTrace();
                return false;
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
            
            return true;
        } catch(NoResultException e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }

    }  
    
    public boolean delete(long id) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Exchange e = em.find(Exchange.class, new Long(id));
            em.remove(e);            
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public List<pl.edu.pk.mech.kkbus.dto.Exchange> getExchangesForUser(long id) {
        List<pl.edu.pk.mech.kkbus.dto.Exchange> result = 
                new LinkedList<pl.edu.pk.mech.kkbus.dto.Exchange>();
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Query query = em.createQuery("SELECT e FROM Exchange e WHERE e.userId = :userId");
            query.setParameter("userId", id);
            List<Exchange> results = (List<Exchange>) query.getResultList();
            Iterator<Exchange> iterator = results.iterator();
            while (iterator.hasNext()) {                
                Exchange e = iterator.next();
                Award a = em.find(Award.class, new Long(e.getAwardId()));
                if (a == null) continue;
                
                result.add(new pl.edu.pk.mech.kkbus.dto.Exchange(e.getKey().getId(),
                        id, a.getKey().getId(), e.getHash(), a.getName()));
            }
            
            return result;
        } catch(NoResultException e) {
            return null;
        } finally {
            if (em != null)
                em.close();
        }
    }
}
